package org.ands.apps;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.xml.namespace.NamespaceContext;

import org.ands.client.TopicFactory;
import org.ands.client.TopicFactory.Topic;
import org.ands.client.aad.ContentsRetrieverAAD;
import org.ands.client.ala.ContentsRetrieverALA;
import org.ands.client.ala.ContentsRetrieverALASpatial;
import org.ands.data.Contents;
import org.ands.data.IClientContentsRetriever;
import org.ands.rifcs.RifCsNamespaceContext;
import org.ands.rifcs.RifCsXmlCleaner;
import org.ands.xml.DOMHelper;
import org.ands.xml.DOMHelperFromFile;
import org.ands.xml.ISchemaRules;

// TODO: Auto-generated Javadoc
/**
 * The Class ComponentManager.
 */
public class ComponentManager {
	
	private static Map<String, TopicFactory.Topic> _TopicConfigMap = new HashMap<String, TopicFactory.Topic>();
	static {
		_TopicConfigMap.put(PropertyHelper.ALA_DATA_RESOURCES_DATA_PROVIDERS, TopicFactory.Topic.ALA_DATA_RESOURCES_DATA_PROVIDERS);
		_TopicConfigMap.put(PropertyHelper.ALA_SPATIAL, TopicFactory.Topic.ALA_SPATIAL);
		_TopicConfigMap.put(PropertyHelper.ALA_SPECIES, TopicFactory.Topic.ALA_SPECIES);
		_TopicConfigMap.put(PropertyHelper.AAD, TopicFactory.Topic.AAD);
		_TopicConfigMap.put(PropertyHelper.AIMS_OAIPHM, TopicFactory.Topic.AIMS_OAIPMH);
		_TopicConfigMap.put(PropertyHelper.AIMS_FILE, TopicFactory.Topic.AIMS_FILE);
		_TopicConfigMap.put(PropertyHelper.AIMS_URI, TopicFactory.Topic.AIMS_URI);
		_TopicConfigMap.put(PropertyHelper.AODN_OAIPMH, TopicFactory.Topic.AODN_OAIPMH);
		_TopicConfigMap.put(PropertyHelper.AODN_FILE, TopicFactory.Topic.AODN_FILE);
		_TopicConfigMap.put(PropertyHelper.AODN_URI, TopicFactory.Topic.AODN_URI);
		_TopicConfigMap.put(PropertyHelper.TEST_OAIPMH, TopicFactory.Topic.TEST_OAIPMH);
		_TopicConfigMap.put(PropertyHelper.TEST_URI, TopicFactory.Topic.TEST_URI);
    }

	
	/**
	 * Run.
	 *
	 * @param properties the properties
	 * @throws Exception the exception
	 */
	public void generateRifCs(final Properties properties) throws Exception{
		PropertyHelper propertyHelper = new PropertyHelper(properties);
		assert(propertyHelper != null);
		
		for(Map.Entry<String, TopicFactory.Topic> entry : _TopicConfigMap.entrySet()){
		
			String value = propertyHelper.getProperty(entry.getKey(), false);
			if(value != null){ // Property is present - no value required so ok if empty
				generateTopicRIFCS(entry.getValue(), propertyHelper);
			}
		}
	}
	
	public void cleanRIFCS(final Properties properties) throws Exception{
		PropertyHelper propertyHelper = new PropertyHelper(properties);
		assert(propertyHelper != null);
		
		String stringTopic = propertyHelper.getProperty("TOPIC", true);
		Topic topic = TopicFactory.getTopicFromString(stringTopic);
		
		String xmlInFileName = propertyHelper.getProperty("RIF_CS_XML_IN", true);
		String xmlOutFileName = propertyHelper.getProperty("RIF_CS_XML_OUT", true);
		
		assert(xmlInFileName != null);
		
		DOMHelperFromFile domHelper = new DOMHelperFromFile(xmlInFileName);
		
		
		DOMHelper cleanDOMHelper = cleanDocument(topic, domHelper);
		
		cleanDOMHelper.writeToFile(xmlOutFileName);
		
	}
	
	/**
	 * Generate topic rifcs.
	 *
	 * @param topic the topic
	 * @param propertyHelper the property helper
	 * @throws Exception the exception
	 */
	private void generateTopicRIFCS(final TopicFactory.Topic topic, final PropertyHelper propertyHelper) throws Exception{
		
		IClientContentsRetriever contentsRetriever = TopicFactory.getTopicRetriever(topic);
		Map<Integer, List<Contents>> xmlContentsAllRegistryObjectsMap = getTopicContents(contentsRetriever, propertyHelper);
		if(xmlContentsAllRegistryObjectsMap.isEmpty()){
			throw new Exception("Requires non-empty list of XMLContents");
		}
		
		String xmlOutFileName = contentsRetriever.getOutFileFromConfig(propertyHelper);
				
		DOMDocumentConstructor domDocumentConstructor = new DOMDocumentConstructor();
		
		Map<String, String> docRootAttributeMap = new HashMap<String, String>();
		
		String namespaceURI = "http://ands.org.au/standards/rif-cs/registryObjects";
		
		docRootAttributeMap.put("xmlns", namespaceURI);
		docRootAttributeMap.put("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
		docRootAttributeMap.put("xsi:schemaLocation", "http://ands.org.au/standards/rif-cs/registryObjects");

		RifCsNamespaceContext namespaceContext = new RifCsNamespaceContext();
		DOMHelper domHelper= domDocumentConstructor.documentFromXMLContents((NamespaceContext)namespaceContext, namespaceURI, "registryObjects", docRootAttributeMap, xmlContentsAllRegistryObjectsMap);
		
		if(propertyHelper.getProperty(PropertyHelper.CLEAN_DOCUMENT, false) != null){
		
			System.out.println("Cleaning document because CLEAN_DOCUMENT is in Config.properties");
			DOMHelper cleanedDOMHelper = cleanDocument(topic, domHelper);
			assert(cleanedDOMHelper != null);
			
			cleanedDOMHelper.writeToFile(xmlOutFileName);
			return;
		}
		
		System.out.println("Not cleaning document because CLEAN_DOCUMENT is not in Config.properties");
		domHelper.writeToFile(xmlOutFileName);
		
	}
	
	private DOMHelper cleanDocument(final TopicFactory.Topic topic, final DOMHelper domHelper) throws Exception{
		assert(domHelper != null);
		
		RifCsXmlCleaner cleaner = new RifCsXmlCleaner();
		
		ISchemaRules rifCsSchemaRules = TopicFactory.getTopicRifcsSchemaRules(topic);
		assert(rifCsSchemaRules != null);
		DOMHelper cleanedDOMHelper = cleaner.cleanDocument(domHelper, rifCsSchemaRules);
		
		return cleanedDOMHelper;
		
	}
	
	
	
	/**
	 * Gets the topic contents.
	 *
	 * @param contentsRetriever the contents retriever
	 * @param propertyHelper the property helper
	 * @return the topic contents
	 * @throws Exception the exception
	 */
	private Map<Integer, List<Contents>> getTopicContents(final IClientContentsRetriever contentsRetriever, final PropertyHelper propertyHelper) throws Exception{
		
		assert(contentsRetriever != null);
		
		Map<Integer, List<Contents>> xmlContentsAllRegistryObjectsMap = contentsRetriever.getXmlContentsFromClient(propertyHelper);
		
		assert(xmlContentsAllRegistryObjectsMap != null);
		assert(!xmlContentsAllRegistryObjectsMap.isEmpty());
		return xmlContentsAllRegistryObjectsMap;
	}

}


